package com.talkology.pilot.student.service.impl;

import com.talkology.pilot.common.enumeration.CourseStatus;
import com.talkology.pilot.common.util.DateTimeUtil;
import com.talkology.pilot.common.util.SendEmail;
import com.talkology.pilot.database.dao.*;
import com.talkology.pilot.database.model.*;
import com.talkology.pilot.student.model.SalonBookingRest;
import com.talkology.pilot.student.service.ISalonBookingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.mail.MessagingException;
import java.util.Date;
import java.util.List;

@Service
public class SalonBookingServiceImpl implements ISalonBookingService {
    private static final Logger LOG = LoggerFactory.getLogger(SalonBookingServiceImpl.class);

    @Autowired
    private TalkSalonBookingsMapper talkSalonBookingsMapper;

    @Autowired
    private TalkSalonMgtMapper talkSalonMgtMapper;

    @Autowired
    private CreditManagerMapper creditManagerMapper;

    @Autowired
    private PayCountMapper payCountMapper;

    @Autowired
    private TeacherInfoMapper teacherInfoMapper;

    @Autowired
    private TeachersTimeMgtMapper timeMgtMapper;

    @Override
    public List<TalkSalonBooking> getAllByFilter(String talkSalonName, String studentId, String teacherName,
                                                 String classBegin, String classEnd, String status) {
        return talkSalonBookingsMapper.getAllByFilter(talkSalonName, studentId, teacherName, classBegin, classEnd, status);
    }

    @Override
    @Transactional
    public void addSalonBookings(SalonBookingRest record) {
        Byte payType = record.getPayType();
        TalkSalonMgt talkSalonMgt = talkSalonMgtMapper.selectByName(record.getTalkSalonName());
        String studentId = record.getStudentId();
        if (payType == 1) {
            Integer creditNum = talkSalonMgt.getUseCredit();
            CreditManager creditManager = creditManagerMapper.selectByStudentId(studentId);
            if (talkSalonMgt.getUsedNum().equals(talkSalonMgt.getStudentLimit())) {
                throw new RuntimeException("该课程预定人数已满！");
            }
            double last = creditManager.getCreditLast() - creditNum;
            if (last < 0) {
                throw new RuntimeException("没有足够学分，请及时充值或者使用在线支付！");
            }
            creditManager.setCreditLast(last);
            creditManagerMapper.updateByPrimaryKey(creditManager);
        }
        if (payType == 2) {
            //TODO 要做订单查询 和检验
        }
        List<TeachersTimeMgt> teachersTimes = timeMgtMapper.selectByFilter(null, record.getTalkSalonName(), null);
        int count = 1;
        for (TeachersTimeMgt teachersTime : teachersTimes) {
            TalkSalonBooking booking = new TalkSalonBooking();
            booking.setTalkSalonName(record.getTalkSalonName());
            booking.setBookingTime(new Date());
            booking.setClassTime(teachersTime.getAvailableTime());
            booking.setStudentId(studentId);
            booking.setStudentName(record.getStudentName());
            booking.setStatus(CourseStatus.PENDING.getName());
            booking.setPayType(record.getPayType());
            booking.setPayId(record.getPayId());
            booking.setSubject(talkSalonMgt.getSubject());
            booking.setClassCount(count);
            count++;
            talkSalonBookingsMapper.insert(booking);
        }
        talkSalonMgt.setUsedNum(talkSalonMgt.getUsedNum() + 1);
        talkSalonMgtMapper.updateByPrimaryKey(talkSalonMgt);
        TeacherInfo teacherInfo = teacherInfoMapper.selectByName(talkSalonMgt.getTeacher());
        String email = teacherInfo.getEmail();
        try {
            SendEmail.sendEmail(email, "New Talk Salon Booking", studentId);
        } catch (MessagingException e) {
            LOG.error("{}", e);
        }
    }

    @Override
    @Transactional
    public void editSalonBookings(TalkSalonBooking record) {
        talkSalonBookingsMapper.updateByPrimaryKey(record);
    }

    @Override
    @Transactional
    public void cancel(String talkSalonName, String studentId, List<String> timeItems) {
        timeItems.removeIf(item -> {
            Date dataIn = DateTimeUtil.convertAsDate(item);
            Date checkDate = DateTimeUtil.dayAddNum(new Date(), 1);
            return checkDate.getTime() > dataIn.getTime();
        });
        List<TalkSalonBooking> talkSalonBookings = talkSalonBookingsMapper
                .getAllByFilter(talkSalonName, studentId, null, null, null, null);
        CreditManager creditManager = creditManagerMapper.selectByStudentId(studentId);
        double creditLast = creditManager.getCreditLast();

        for(TalkSalonBooking booking : talkSalonBookings) {
            String courseTime = DateTimeUtil.timeToStrFormat(booking.getClassTime());
            if (timeItems.contains(courseTime)) {
                booking.setStatus(CourseStatus.CANCELED.getName());
                booking.setCancelType((byte) 2);
                talkSalonBookingsMapper.updateByPrimaryKey(booking);
                creditLast = creditLast + 0.5;
            }
        }
        creditManager.setCreditLast(creditLast);
        creditManagerMapper.updateByPrimaryKey(creditManager);
    }
}
